package com.ark.frigate.mybatis.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
 * @author zengweilong
 */
public class FileUtils {

    private static Logger logger = LoggerFactory.getLogger(FileUtils.class);

    /**
     * 读取文件内容
     *
     * @param filePath 文件名称
     * @return String
     */
    public static String readContent(String filePath) {

        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new File(filePath));
            return FileUtils.readContent(fis, StandardCharsets.UTF_8);
        } catch (Exception e) {
            logger.error("Read file stream error.", e);
        } finally {
            if (null != fis) {
                try {
                    fis.close();
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return null;
    }

    /**
     * 读取文件内容
     *
     * @param fileName 文件
     * @param charset  编码
     * @return String
     */
    public static String readContent(File fileName, Charset charset) {

        try {
            InputStream inputStream = new FileInputStream(fileName);
            return readContent(inputStream, charset);
        } catch (IOException e) {
            logger.error("Read File Error!" + e.getMessage(), e);
        }
        return null;
    }

    /**
     * 读取文件内容
     *
     * @param inputStream 文件输入流
     * @param charset     文件编码
     * @return String
     */
    public static String readContent(InputStream inputStream, Charset charset) {

        StringBuilder result = new StringBuilder();
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        try {
            inputStreamReader = new InputStreamReader(inputStream, charset);
            // 构造一个BufferedReader类来读取文件
            bufferedReader = new BufferedReader(inputStreamReader);
            String line = null;
            // 使用readLine方法，一次读一行
            while ((line = bufferedReader.readLine()) != null) {
                result.append(line + "\n");
            }
        } catch (Exception e) {
            logger.error("Read file stream error.", e);
        } finally {
            try {
                if (null != bufferedReader) {
                    bufferedReader.close();
                }
                if (null != inputStreamReader) {
                    inputStreamReader.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception ex) {
                logger.error("Close file stream error.", ex);
            }
        }

        return result.toString();
    }

    /**
     * 根据内容和目录写入文件
     *
     * @param file    待写入路径
     * @param content 待写入内容
     * @return boolean 状态
     */
    public static boolean writeContent(File file, String content) {

        return writeContent(file, content, StandardCharsets.UTF_8);
    }

    /**
     * 根据内容和目录写入文件
     *
     * @param file    待写入路径
     * @param content 待写入内容
     * @param charset 编码
     * @return boolean 状态
     */
    public static boolean writeContent(File file, String content, Charset charset) {

        String dir = file.getPath().substring(0, file.getPath().lastIndexOf(File.separator));
        File folder = new File(dir);
        if (!folder.exists()) {
            boolean createFolder = folder.mkdirs();
            logger.info("文件创建结束，{}", createFolder);
        }
        // 写入
        OutputStream outputStream = null;
        OutputStreamWriter outputStreamWriter = null;
        BufferedWriter bufferedWriter = null;
        try {
            outputStream = new FileOutputStream(file);
            outputStreamWriter = new OutputStreamWriter(outputStream, charset);
            bufferedWriter = new BufferedWriter(outputStreamWriter);
            bufferedWriter.write(content);
            bufferedWriter.newLine();
            bufferedWriter.flush();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
            return false;
        } finally {
            try {
                if (null != bufferedWriter) {
                    bufferedWriter.close();
                }
                if (null != outputStreamWriter) {
                    outputStreamWriter.close();
                }
                if (null != outputStream) {
                    outputStream.close();
                }
            } catch (IOException e) {
                logger.error("已关闭", e);
            }
        }
        return true;
    }

    /**
     * 根据内容和目录写入文件
     *
     * @param file        待写入路径
     * @param inputStream 待写入内容
     * @param charset     编码
     * @return boolean 状态
     */
    public static boolean writeContent(File file, InputStream inputStream, Charset charset) {

        String dir = file.getPath().substring(0, file.getPath().lastIndexOf(File.separator));
        File folder = new File(dir);
        if (!folder.exists()) {
            boolean createFolder = folder.mkdirs();
            logger.info("文件创建结束，{}", createFolder);
        }
        // 写入
        OutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            byte[] b = new byte[1024];
            while ((inputStream.read(b)) != -1) {
                outputStream.write(b);
            }
            outputStream.flush();
            outputStream.close();
            return true;
        } catch (IOException e) {
            logger.error("文件写入失败", e);
            return false;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                logger.error("已关闭", e);
            }
        }
    }

    /**
     * 根据内容和目录写入文件
     *
     * @param filePath 待写入路径
     * @param content  待写入内容
     * @return boolean 状态
     */
    public static boolean writeContent(String filePath, String content) {

        File file = new File(filePath);
        return writeContent(file, content, StandardCharsets.UTF_8);
    }

}
